/// -----------------------------------------------------------------------------------------------------------
/// Module      :  QueueStorageAdapter.cs
/// Description :  The main adapter class which inherits from Adapter
/// -----------------------------------------------------------------------------------------------------------

#region Using Directives

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

using Microsoft.ServiceModel.Channels.Common;

#endregion

namespace BizTalkFactory.Adapters.AzureStorage
{
    public class AzureStorageAdapter : Adapter
    {
        // Scheme associated with the adapter
        internal const string SCHEME = "azure";
        // Namespace for the proxy that will be generated from the adapter schema
        internal const string SERVICENAMESPACE = "http://schemas.biztalk.adapter/2011/azure.storage";
        // Initializes the AdapterEnvironmentSettings class
        private static AdapterEnvironmentSettings environmentSettings = new AdapterEnvironmentSettings();

        #region  Constructor

        /// <summary>
        /// Initializes a new instance of the AzureStorageAdapter class
        /// </summary>
        public AzureStorageAdapter()
            : base(environmentSettings)
        {
            Settings.Metadata.DefaultMetadataNamespace = SERVICENAMESPACE;            
            Settings.Metadata.CompileWsdl = true;
        }

        /// <summary>
        /// Initializes a new instance of the AzureStorageAdapter class with a binding
        /// </summary>
        public AzureStorageAdapter(AzureStorageAdapter binding)
            : base(binding)
        {
            this.PollingIntervalInSeconds = binding.PollingIntervalInSeconds;
            this.PollingStorage = binding.PollingStorage;

            this.BlobMask = binding.BlobMask;

            this.DevelopmentStorageProxyUri = binding.DevelopmentStorageProxyUri;
            this.AccountKey = binding.AccountKey;
            this.DefaultEndpointsProtocol = binding.DefaultEndpointsProtocol;
            this.BlobEndpoint = binding.BlobEndpoint;
            this.QueueEndpoint = binding.QueueEndpoint;
            this.TableEndpoint = binding.TableEndpoint;
            this.SharedAccessSignature = binding.SharedAccessSignature;
        }

        #endregion Constructor

        #region Custom Generated Properties

        // General Properties

        // Inbound Properties

        [System.Configuration.ConfigurationProperty("pollingIntervalInSeconds", DefaultValue = 30)]
        public Int32 PollingIntervalInSeconds { get; set; }

        [System.Configuration.ConfigurationProperty("pollingStorage", DefaultValue = StorageType.Unspecified)]
        public StorageType PollingStorage { get; set; }

        [System.Configuration.ConfigurationProperty("blobMask", DefaultValue = "")]
        public String BlobMask { get; set; }

        // Local Storage Emulator Connection String Parameters

        [System.Configuration.ConfigurationProperty("developmentStorageProxyUri", DefaultValue = "")]
        public string DevelopmentStorageProxyUri { get; set; }

        // Azure Storage Connection String Parameters

        [System.Configuration.ConfigurationProperty("accountKey", DefaultValue = AzureStorageAdapterConnectionUri.DevelopmentStorageAccountkey)]
        public String AccountKey { get; set; }

        [System.Configuration.ConfigurationProperty("defaultEndpointsProtocol", DefaultValue = "https")]
        public String DefaultEndpointsProtocol { get; set; }

        [System.Configuration.ConfigurationProperty("blobEndpoint", DefaultValue = "")]
        public String BlobEndpoint { get; set; }

        [System.Configuration.ConfigurationProperty("queueEndpoint", DefaultValue = "")]
        public String QueueEndpoint { get; set; }

        [System.Configuration.ConfigurationProperty("tableEndpoint", DefaultValue = "")]
        public String TableEndpoint { get; set; }

        [System.Configuration.ConfigurationProperty("sharedAccessSignature", DefaultValue = "")]
        public String SharedAccessSignature { get; set; }

        #endregion Custom Generated Properties

        #region Public Properties

        /// <summary>
        /// Gets the URI transport scheme that is used by the adapter
        /// </summary>
        public override string Scheme
        {
            get
            {
                return SCHEME;
            }
        }

        #endregion Public Properties

        #region Protected Methods

        /// <summary>
        /// Creates a ConnectionUri instance from the provided Uri
        /// </summary>
        protected override ConnectionUri BuildConnectionUri(Uri uri)
        {
            return new AzureStorageAdapterConnectionUri(uri);
        }

        /// <summary>
        /// Builds a connection factory from the ConnectionUri and ClientCredentials
        /// </summary>
        protected override IConnectionFactory BuildConnectionFactory(
            ConnectionUri connectionUri
            , ClientCredentials clientCredentials
            , System.ServiceModel.Channels.BindingContext context)
        {
            return new AzureStorageAdapterConnectionFactory(connectionUri, clientCredentials, this);
        }

        protected override IWsdlRetrieval BuildWsdlRetrieval(MetadataLookup metadataLookup)
        {
            return new AzureStorageAdapterWsdlRetrieval(base.BuildWsdlRetrieval(metadataLookup));
        }

        /// <summary>
        /// Returns a clone of the adapter object
        /// </summary>
        protected override Adapter CloneAdapter()
        {
            return new AzureStorageAdapter(this);
        }

        /// <summary>
        /// Indicates whether the provided TConnectionHandler is supported by the adapter or not
        /// </summary>
        protected override bool IsHandlerSupported<TConnectionHandler>()
        {
            return (
                   typeof(IInboundHandler) == typeof(TConnectionHandler))
                || typeof(IOutboundHandler) == typeof(TConnectionHandler)
                || typeof(IMetadataBrowseHandler) == typeof(TConnectionHandler)
                || typeof(IMetadataResolverHandler) == typeof(TConnectionHandler)
                ;
        }

        /// <summary>
        /// Gets the namespace that is used when generating schema and WSDL
        /// </summary>
        protected override string Namespace
        {
            get { return SERVICENAMESPACE; }
        }

        #endregion Protected Methods
    }
}
